﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

using SBPweb.RIA.Shared.Contracts.Components;
using SBPweb.RIA.Shared.Contracts.Events;

using SBPweb.PROvibe.Server.Library.Contracts;
using SBPweb.PROvibe.Server.Library.Services;
using SBPweb.PROvibe.Shared.Library.Components;

namespace SBPweb.PROvibe.Server.Library.Modularity
{

    public abstract class ServerModuleBase : ServerModule, IInitializable
    {

        #region Constructor logic

        protected ServerModuleBase()
        {
            Type type = this.GetType();
            Name = type.Name;
            Version = type.Assembly.GetName().Version;
        }

        #endregion

        #region Properties

        protected virtual IServerContext ServerContext
        {
            get;
            private set;
        }

        public override ReadOnlyCollection<IService> Services
        {
            get
            {
                if (ServerContext == null)
                {
                    return null;
                }
                return new ReadOnlyCollection<IService>(ServerContext.ServiceManager.Services.Where(x => x.Parent == this).ToList());
            }
        }

        public ReadOnlyCollection<IService> PublicServices
        {
            get
            {
                return ServerContext.ServiceManager.Services;
            }
        }

        public bool IsInitialized
        {
            get;
            private set;
        }

        #endregion

        #region Events

        public event EventHandler<CancelEventArgs> Initializing;

        public event EventHandler Initialized;

        public event EventHandler<CancelEventArgs> Terminating;

        public event EventHandler Terminated;

        #endregion

        #region Methods

        public void AssignServerContext(IServerContext context)
        {
            ServerContext = context;
            OnServerContextAssigning();
        }

        public void Initialize()
        {
            CancelEventArgs cea = new CancelEventArgs(false);
            OnInitializing(cea);
            if (Initializing != null)
            {
                Initializing(this, cea);
            }
            if (cea.Cancel)
            {
                return;
            }
            IsInitialized = true;
            OnInitialized();
            if (Initialized != null)
            {
                Initialized(this, EventArgs.Empty);
            }
        }
        
        public void Terminate()
        {
            CancelEventArgs cea = new CancelEventArgs(false);
            OnTerminating(cea);
            if (Terminating != null)
            {
                Terminating(this, cea);
            }
            if (cea.Cancel)
            {
                return;
            }
            IsInitialized = false;
            OnTerminated();
            if (Terminated != null)
            {
                Terminated(this, EventArgs.Empty);
            }
        }

        protected virtual void OnServerContextAssigning()
        {
        }

        protected virtual void OnInitializing(CancelEventArgs e)
        {
        }

        protected virtual void OnInitialized()
        {
        }

        protected virtual void OnTerminating(CancelEventArgs e)
        {
        }

        protected virtual void OnTerminated()
        {
        }

        #endregion

    }

}